// import $ from './lib/jquery';
import Hooks from './common/hooks';
import tools from './common/tools';
import undoRedo from './common/undoRedo';
import grouper from './component/group';

function isFormula(value) {
    if (value&&value[0] === '=') {
        return true;
    }
    return false;
}

function arrayFilter(data,t,c){
    if(c!=undefined){
        return data.filter(function(item) {
            if(item.c==c) return item;
        });
    }else{
        return data.filter(function(item) {
            if(item.t==t) return item;
        });
    }
}

function arrayValue(data){
    var result=[];
    data.forEach(function(v){
        var dv=$.trim(v.v);
        result.push(dv);
    });
    return result;
}

var textCell = {
    renderer: Handsontable.renderers.TextRenderer,
    editor: Handsontable.editors.TextEditor
};
var numericCell = {
    renderer: Handsontable.renderers.NumericRenderer,
    editor: Handsontable.editors.NumericEditor
};
Handsontable.hooks.add('beforeInit',Formula);
Handsontable.hooks.add('afterUpdateSettings', function () {
  Formula.call(this, 'afterUpdateSettings')
});
function Formula(){
    var instance=this;
    var custom = {
        cellValue: instance.getDataAtCell
    };
    instance.plugin = new ruleJS();
    instance.plugin.init();
    instance.plugin.custom = custom;
}
  
/**
 * [sheets interface]
 * // class funcs
 * init()
 * addHook()
 * saveChart(evt,data)
 *
 * // sheet funcs
 * open(id:string)
 * save()
 * redraw()
 * getSheet()
 * addSheet(id,name)
 * toArray(sheet)
 * addRow()
 * delRow()
 * addCol()
 * delCol()
 * removeEmptyItem()
 * parseHeader
 * setSheetColHeader(r,c,lr,lc)
 * setSheetRowHeader(r,c,lr,lc)
 *
 * // cell funcs
 * getCell(r,c,auto)
 * setCell(r,c,d)
 * delCell(r,c)
 * isEmptyCell(r,c)
 * getCellProp(r,c,k)
 * setCellProp(r,c,k,v)
 * updateSelectedCells
 * updateCells
 * mergeCells
 * unMergeCells
 * isMergeCell
 * inMergeCells
 */
 
 class sheets {
     constructor(dom='body'){
        this.usetype=0; //0:编辑模式，1:接口模式，2:自解析模式
        this.selected=null;
        this.grouper=null;
        this.dom=dom;
        this.handsontable=null;
        this.hooks=new Hooks();
     }

     saveChart(data){
         this.hooks.dispatch('savechart',data);
     }
     
     init(){
        var that=this;
        this.handsontable = new Handsontable(document.getElementById(this.dom), {
            startRows: this.sheet.minrows,
            startCols: this.sheet.mincols,
            colHeaders: this.sheet.colHeaders||true,
            rowHeaders: this.sheet.rowHeaders||true,
            minSpareRows: 1,
            minSpareCols:1,
            formulas:true,
            fillHandle:true,           //拖拽复制:true, false, "horizontal", "vertical"
            comments: true,            //允许备注
            manualColumnResize: false, //允许修改列宽
            manualRowResize: false,    //允许修改行高
            manualColumnMove: false,   //允许移动列
            manualRowMove: false,      //允许移动行
            outsideClickDeselects:false,
            data:this.toArray(),
            mergeCells:this.sheet.mergecells||[],//合并cell
            //自定义右击菜单
            contextMenu:{
                callback: function (key, options) {
                    var olddata=tools.extend(true,{},that.sheet.data);
                    var r=options.start.row,c=options.start.col,
                        lr=options.end.row,lc=options.end.col;
                    switch(key){
                    case 'row_above':
                        that.addRow(r,'before',1);
                    break;
                    case 'row_below':
                        that.addRow(lr,'after',1);
                    break;
                    case 'col_left':
                        that.addCol(c,'before',1);
                    break;
                    case 'col_right':
                        that.addCol(lc,'after',1);
                    break;
                    case 'remove_row':
                        that.delRow(r,lr);
                    break;
                    case 'remove_col':
                        that.delCol(c,lc);
                    break;
                    case 'make_read_only':
                        that.lockCell(r,c,lr,lc);
                    break;
                    case 'group':
                        // that.setGroup(r,c,lr,lc);
                    break;
                    case 'chart':
                        // that.setChart(r,c,lr,lc);
                    break;
                    case 'database':
                        // that.setDatabase(r,c,lr,lc);
                    break;
                    case 'merge_cells':
                        that.mergeCells(r,c,lr,lc);
                    break;
                    }
                    if(key=='group'){
                    that.grouper.addGroup(r,c,lr,lc);
                    }else if(key=='chart'){
                    // coding...
                    }else if(key=='database'){
                    // coding...
                    }else if(key=='colhead'){
                    // coding...
                        // console.log('set colhead.');
                        that.setSheetColHeader(r,c,lr,lc);
                    }else if(key=='rowhead'){
                    // coding...
                        // console.log('set rowhead.');
                        that.setSheetRowHeader(r,c,lr,lc);
                    }else{
                        that.redraw();
                    }
                    // var newdata=tools.extend(true,{},that.sheet.data);
                    // undoRedo.add(function(){
                    //   that.sheet.data=newdata;
                    //   that.redraw();
                    // },function(){
                    //   that.sheet.data=olddata;
                    //   that.redraw();
                    // });
                }
                ,items:that.getContextMenus()
            }
            // ,cells:function (row, col, prop){
            //     let cell=that.getCell(row,col);
            //     if(cell){
            //         let cellId = this.instance.plugin.utils.translateCellCoords({row: row, col: col});
            //         let item={
            //             id: cellId,
            //             formula: cell.formula,
            //             value:cell.value,
            //         };
            //         this.instance.plugin.matrix.addItem(item);
            //     }
            // }
            ,afterSelectionEnd:function(r,c,r2,c2){
                that.hooks.dispatch('selectioncell',{r:r,c:c,cell:that.getCell(r,c)});
                that.selected=[r,c,r2,c2];
            }
            ,renderer:function (instance, TD, row, col, prop, value, cellProperties){
                var cellId = instance.plugin.utils.translateCellCoords({row: row, col: col});
                if (isFormula(value)) {
                    // translate coordinates into cellId
                    var prevFormula = null,
                        formula = null,
                        needUpdate = false,
                        error, result;
                    if (!cellId) {
                        return;
                    }
                    // get cell data
                    var item = instance.plugin.matrix.getItem(cellId);
                    if (item) {
                        needUpdate = !!item.needUpdate;
                        if (item.error) {
                            prevFormula = item.formula;
                            error = item.error;

                            if (needUpdate) {
                                error = null;
                            }
                        }
                    }
                    // check if typed formula or cell value should be recalculated
                    if ((value && value[0] === '=') || needUpdate) {
                        formula = value.substr(1).toUpperCase();
                        if (!error || formula !== prevFormula) {
                            var currentItem = item;
                            if (!currentItem) {
                                // define item to rulesJS matrix if not exists
                                item = {
                                    id: cellId,
                                    formula: formula
                                };
                                // add item to matrix
                                currentItem = instance.plugin.matrix.addItem(item);
                            }
                            // parse formula
                            var newValue = instance.plugin.parse(formula, {row: row, col: col, id: cellId});
                            // check if update needed
                            needUpdate = (newValue.error === '#NEED_UPDATE');
                            // update item value and error
                            instance.plugin.matrix.updateItem(currentItem, {formula: formula, value: newValue.result, error: newValue.error, needUpdate: needUpdate});
                            error = newValue.error;
                            result = newValue.result;
                            // update cell value in hot
                            value = error || result;
                        }
                    }
                    if (error) {
                        // clear cell value
                        if (!value) {
                            // reset error
                            error = null;
                        } else {
                            // show error
                            value = error;
                        }
                    }
                    // change background color
                    if (instance.plugin.utils.isSet(error)) {
                        Handsontable.Dom.addClass(TD, 'formula-error');
                    } else if (instance.plugin.utils.isSet(result)) {
                        Handsontable.Dom.removeClass(TD, 'formula-error');
                        Handsontable.Dom.addClass(TD, 'formula');
                    }
                }
                TD.id=cellId;
                // apply changes
                if (cellProperties.type === 'numeric') {
                    numericCell.renderer.apply(this, [instance, TD, row, col, prop, value, cellProperties]);
                } else {
                    textCell.renderer.apply(this, [instance, TD, row, col, prop, value, cellProperties]);
                }
                cellProperties.readOnly=false;
                //update cell
                var cell=that.getCell(row,col);
                if(cell!=null){
                    cell.value=value;
                    cellProperties.readOnly=cell.readonly;
                    if(cellProperties.readOnly==true){
                        Handsontable.Dom.addClass(TD,'locked');
                    }
                    if(tools.isEmptyObject(cell.styles)==false){
                        TD.setAttribute('style',tools.styleFmt(cell.styles));
                    }
                }
            }
            // ,beforeAutofill:function(start,end,data){
            //     console.log('beforeAutofill',start,end,data);
            //     data=[['12']];
            //     return data;
            // }
            ,afterChange:function(changes, source){
                // console.log('afterChange', changes, source);
                var instance = this;
                if (source === 'edit' || source === 'undo' || source === 'autofill' || source==='paste') {
                    var rerender = false;
                    changes.forEach(function (item) {
                        var row = item[0],
                            col = item[1],
                            prevValue = item[2],
                            value = item[3];
                        var cellId = instance.plugin.utils.translateCellCoords({row: row, col: col});
                        // if changed value, all references cells should be recalculated
                        if (prevValue !== value || value[0] !== '=') {
                            instance.plugin.matrix.removeItem(cellId);
                            // get referenced cells
                            var deps = instance.plugin.matrix.getDependencies(cellId);
                            // update cells
                            deps.forEach(function (itemId) {
                                instance.plugin.matrix.updateItem(itemId, {needUpdate: true});
                            });
                            rerender = true;
                        }
                        if(value==null){
                            if(that.isEmptyCell(row,col)==true) that.delCell(row,col);
                        }else{
                            var cell=that.getCell(row,col,true);
                            if(value[0]=='='){
                                cell.formula=value.substr(1).toUpperCase();
                            }else if(value!=null){
                                cell.value=value;
                                cell.formula=null;
                            }
                        }
                    });
                    if (rerender) {
                        instance.render();
                    }
                }
                //修改数值后刷新图表
                that.grouper.refreshChart();
            }
            ,beforeAutofillInsidePopulate:function(index, direction, data, deltas, iterators, selected){
                // console.log('beforeAutofillInsidePopulate');
                var instance = this;
                var r = index.row,
                    c = index.col,
                    value = data[r][c],
                    delta = 0,
                    rlength = data.length, // rows
                    clength = data ? data[0].length : 0; //cols
                if (value&&value[0] === '=') { // formula
                    if (['down', 'up'].indexOf(direction) !== -1) {
                        delta = rlength * iterators.row;
                    } else if (['right', 'left'].indexOf(direction) !== -1) {
                        delta = clength * iterators.col;
                    }
                    return {
                        value: instance.plugin.utils.updateFormula(value, direction, delta),
                        iterators: iterators
                    }
                } else { // other value
                    // increment or decrement  values for more than 2 selected cells
                    if (rlength >= 2 || clength >= 2) {
                        var newValue = instance.plugin.helper.number(value),
                            ii,
                            start;
                        if (instance.plugin.utils.isNumber(newValue)) {
                            if (['down', 'up'].indexOf(direction) !== -1) {
                                delta = deltas[0][c];
                                if (direction === 'down') {
                                    newValue += (delta * rlength * iterators.row);
                                } else {
                                    ii = (selected.row - r) % rlength;
                                    start = ii > 0 ? rlength - ii : 0;
                                    newValue = instance.plugin.helper.number(data[start][c]);
                                    newValue += (delta * rlength * iterators.row);
                                    // last element in array -> decrement iterator
                                    // iterator cannot be less than 1
                                    if (iterators.row > 1 && (start + 1) === rlength) {
                                        iterators.row--;
                                    }
                                }
                            } else if (['right', 'left'].indexOf(direction) !== -1) {
                                delta = deltas[r][0];
                                if (direction === 'right') {
                                    newValue += (delta * clength * iterators.col);
                                } else {
                                    ii = (selected.col - c) % clength;
                                    start = ii > 0 ? clength - ii : 0;
                                    newValue = instance.plugin.helper.number(data[r][start]);
                                    newValue += (delta * clength * (iterators.col || 1));
                                    // last element in array -> decrement iterator
                                    // iterator cannot be less than 1
                                    if (iterators.col > 1 && (start + 1) === clength) {
                                        iterators.col--;
                                    }
                                }
                            }
                            return {
                                value: newValue,
                                iterators: iterators
                            }
                        }
                    }
                }
                return {
                    value: value,
                    iterators: iterators
                };
            }
            ,afterCreateRow:function(row, amount, auto){
                // console.log('afterCreateRow',row, amount, auto);
                if (auto) {
                    return;
                }
                var instance = this;
                var selectedRow = instance.plugin.utils.isArray(instance.getSelected()) ? instance.getSelected()[0] : undefined;
                if (instance.plugin.utils.isUndefined(selectedRow)) {
                    return;
                }
                var direction = (selectedRow >= row) ? 'before' : 'after',
                    items = instance.plugin.matrix.getRefItemsToRow(row),
                    counter = 1,
                    changes = [];
                items.forEach(function (id) {
                    var item = instance.plugin.matrix.getItem(id),
                    formula = instance.plugin.utils.changeFormula(item.formula, 1, {row: row}), // update formula if needed
                    newId = id;
                    if (formula !== item.formula) { // formula updated
                        // change row index and get new coordinates
                        if ((direction === 'before' && selectedRow <= item.row) || (direction === 'after' && selectedRow < item.row)) {
                            newId = instance.plugin.utils.changeRowIndex(id, counter);
                        }
                        var cellCoords = instance.plugin.utils.cellCoords(newId);
                        if (newId !== id) {
                            // remove current item from matrix
                            instance.plugin.matrix.removeItem(id);
                        }
                        // set updated formula in new cell
                        changes.push([cellCoords.row, cellCoords.col, '=' + formula]);
                    }
                });
                if (items) {
                    instance.plugin.matrix.removeItemsBelowRow(row);
                }
                if (changes) {
                    instance.setDataAtCell(changes);
                }
            }
            ,afterCreateCol:function(col){
                // console.log('afterCreateCol',col);
                var instance = this;
                var selectedCol = instance.plugin.utils.isArray(instance.getSelected()) ? instance.getSelected()[1] : undefined;
                if (instance.plugin.utils.isUndefined(selectedCol)) {
                    return;
                }
                var items = instance.plugin.matrix.getRefItemsToColumn(col),
                    counter = 1,
                    direction = (selectedCol >= col) ? 'before' : 'after',
                    changes = [];
                items.forEach(function (id) {
                    // console.log('afterCreateCol',id);
                    var item = instance.plugin.matrix.getItem(id),
                    formula = instance.plugin.utils.changeFormula(item.formula, 1, {col: col}), // update formula if needed
                    newId = id;
                    if (formula !== item.formula) { // formula updated
                        // change col index and get new coordinates
                        if ((direction === 'before' && selectedCol <= item.col) || (direction === 'after' && selectedCol < item.col)) {
                            newId = instance.plugin.utils.changeColIndex(id, counter);
                        }
                        var cellCoords = instance.plugin.utils.cellCoords(newId);
                        if (newId !== id) {
                            // remove current item from matrix if id changed
                            instance.plugin.matrix.removeItem(id);
                        }
                        // set updated formula in new cell
                        changes.push([cellCoords.row, cellCoords.col, '=' + formula]);
                    }
                });
                if (items) {
                    instance.plugin.matrix.removeItemsBelowCol(col);
                }
                if (changes) {
                    instance.setDataAtCell(changes);
                }
            }
        });
    }
    getContextMenus(){
        // console.log('getContextMenus',this.usetype);
        if(this.usetype===0){
            return {
                    row_above:{_name:'插入行（上方）'},
                    row_below:{_name:'插入行（下方）'},
                    hsep1: "---------",
                    col_left:{_name:'插入列（左边）'},
                    col_right:{_name:'插入列（右边）'},
                    hsep2: "---------",
                    remove_row:{_name:'删除行'},
                    remove_col:{_name:'删除列'},
                    hsep3: "---------",
                    merge_cells:{name: function() {
                        var sel = this.getSelected();
                        var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]);
                        if (info) {
                            return '拆分单元格'//'Unmerge cells';
                        } else {
                            return '合并单元格'//'Merge cells';
                        }
                    }},
                    // undo:{name:'撤销'},
                    // redo:{name:'重做'},
                    make_read_only:{_name:'设为只读'}, 
                    hsep4: "---------",
                    group:{name:'编组'},
                    colhead:{name:'设为列头'},
                    rowhead:{name:'设为行头'},
                    // chart:{name:'映射到图表'},
                    // database:{name:'映射到数据库'}
                }
        }else if(this.usetype===1){
            return {version:{name:'Version 0.9'}}
        }else{
            return {group:{name:'编组'},version:{name:'Version 0.9'}}
        }
    }
    //添加事件
    addHook(n,fn){
        this.hooks.addHook(n,fn);
    }
    lockCell(r,c,r2,c2){
        var k='readonly',cell=this.getCell(r,c);
        var v=cell&&cell.readonly||false;
        this.updateCells(r,c,r2,c2,k,!v);
    }
    // sheets funcs
    open(sheets,usetype){
        let that=this;
        this.usetype=usetype||0;
        this.selected=null;
        this.sheets=sheets;
        this.sheet=this.sheets[0];
        if(this.grouper===null){
            this.grouper=new grouper(this.sheet.groups,this);
        }else{
            this.grouper.reset(this.sheet.groups,this);
        }
        if(this.handsontable==null){
            this.init();
        }else{
            this.update();
        }
    }
  	select(id){
        // 先保存
        this.save();
        // 还原设置
        this.selected=null;
        this.sheet=this.getSheet(id);
        this.grouper.reset(this.sheet.groups,this);
        this.update();
  	}
  	save(){
        this.removeEmptyItem();
        this.sheet.groups=this.grouper.save();
  		return this.sheets;
  	}
    update(){
        var options={
            startRows: this.sheet.minrows
            , startCols: this.sheet.mincols
            , colHeaders: this.sheet.colHeaders||true
            , rowHeaders: this.sheet.rowHeaders||true
            , data:this.toArray()
            , mergeCells:this.sheet.mergecells||[]//合并cell
            , contextMenu:{
                items:this.getContextMenus()
            }
        }
        this.handsontable.updateSettings(options);
        this.handsontable.render();
    }
  	redraw(){
        this.handsontable.render();
  	}
  	getSheet(id){
        if(id!=undefined){
            for(let i=0,l=this.sheets.length;i<l;i++){
                if(this.sheets[i].id===id) return this.sheets[i];
            }
        }
  		return null;
  	}
    addSheet(id,name){
        let sheet=tools.generateSheet(id,name);
        this.sheets.push(sheet);
        this.select(id);
    }
    toArray(){
        var r=this.sheet.minrows,c=this.sheet.mincols,data=this.sheet.data,i=0,rows=[];
        for(;i<r;i++){
            var cols=[];
            for(var m=0;m<c;m++){
            cols.push((data&&data[i*c+m]&&data[i*c+m].value)||null);
            }
            rows.push(cols);
        }
        return rows;
    }
    addRow(r,direction,n){
        var data=tools.extend(true,{},this.sheet.data),d,_r,_c;
        for( var item in data){
            if((direction=='after'&&data[item].r>r)
            ||(direction=='before'&&data[item].r>=r)){
                d=data[item],_r=d.r,_c=d.c;
                d.r=_r+n;
                this.setCell(d.r,d.c,d);
                this.delCell(_r,_c);
            }
        }
    }
    delRow(r,r2){
        var data=tools.extend(true,{},this.sheet.data),
            n=r2-r+1,d,_r,_c;
        for( var item in data){
            d=data[item],_r=d.r,_c=d.c;
            if(_r>=r&&_r<=r2){
                this.delCell(_r,_c);
            }else if(_r>r2){
                d.r=_r-n;
                this.setCell(d.r,d.c,d);
                this.delCell(_r,_c);
            }
        }
    }
    addCol(c,direction,n){
        var data=tools.extend({},this.sheet.data),d,_r,_c;
        for( var item in data){
            if((direction=='after'&&data[item].c>c)
                ||(direction=='before'&&data[item].c>=c)){
                
                d=data[item],_r=d.r,_c=d.c;
                d.c=_c+n;
                this.setCell(d.r,d.c,d);
                this.delCell(_r,_c);
            }
        }
    }
    delCol(c,c2){
        var data=tools.extend(true,{},this.sheet.data),
            n=c2-c+1,d,_r,_c;
        for( var item in data){
            d=data[item],_r=d.r,_c=d.c;
            if(_c>=c&&_c<=c2){
                this.delCell(_r,_c);
            }else if(_c>c2){
                d.c=_c-n;
                this.setCell(d.r,d.c,d);
                this.delCell(_r,_c);
            }
        }
    }
    removeEmptyItem(){
        var data=this.sheet.data;
        for(var i in data){
            if(this.isEmptyCell(data[i].r,data[i].c)==true){
                this.delCell(data[i].r,data[i].c);
            }
        }
    }
    setSheetColHeader(r,c,lr,lc){
        this.sheet.colheader=[];
        for(;r<=lr;r++){
            for(let _c=c;_c<=lc;_c++){
                let cell=this.getCell(r,_c,false);
                this.sheet.colheader.push(cell);
            }
        }
        // this.sheet.mincols=lc+1;
    }
    setSheetRowHeader(r,c,lr,lc){
        this.sheet.rowheader=[];
        for(;r<=lr;r++){
           for(let _c=c;_c<=lc;_c++){
                let cell=this.getCell(r,_c,false);
                this.sheet.rowheader.push(cell);
            }
        }
        // this.sheet.minrows=lr+1;
    }

    //cell funcs
    getCell(r,c,auto){
        var id=r*this.sheet.mincols+c;
        if(this.sheet.data[id]==undefined&&auto==true){
            this.sheet.data[id]=tools.newcell(r,c);
        }
        return this.sheet.data[id]==undefined?null:this.sheet.data[id];
    }
    setCell(r,c,d){
        var id=r*this.sheet.mincols+c;
        this.sheet.data[id]=d;
    }
    delCell(r,c){
        var id=r*this.sheet.mincols+c;
        if(this.sheet.data[id]!=undefined){
            delete this.sheet.data[id];
        }
    }
    isEmptyCell(r,c){
        var cell=this.getCell(r,c);
        if(cell==null) return true;
        if(cell.value!==null&&cell.value!=='') return false;
        if(cell.formula!==null&&cell.formula!=='') return false;
        if(cell.tips!==null&&cell.tips!=='') return false;
        if(cell.readonly==true) return false;
        for(let i in cell.styles){
            if(cell.styles[i]!=='') return false;
        }
        for(let i in cell.dbopts){
            if(cell.dbopts[i]!=='') return false;
        }
        return true;
    }
    getCellProp(r,c,k){
        var cell=this.getCell(r,c);
        return cell&&cell[k]||null;
    }
    setCellProp(r,c,k,v){
        var cell=this.getCell(r,c,true);
        if(cell.readonly==true&&(k=='formula'||k=='value')) return;
        cell[k]=v;
        if(k=='formula'||k=='value'){
            this.handsontable.setDataAtCell(r,c,v,'edit');
        }else if(k=='readonly'){
            var TD=this.handsontable.getCell(r,c);
            if(v==true){
                Handsontable.Dom.addClass(TD, 'locked');
            }else{
                Handsontable.Dom.removeClass(TD, 'locked');
            }
            this.handsontable.setCellMeta(r,c,'readOnly',v);
        }else if(k=='styles'){
            var TD=this.handsontable.getCell(r,c);
            TD.setAttribute('style',tools.styleFmt(v));
        }
    }
    updateSelectedCells(e,v){
        // console.log('updateSelectedCells',e,v);
        if(this.selected==null) return;
        var r=this.selected[0],
            c=this.selected[1],
            r2=this.selected[2],
            c2=this.selected[3];
        this.updateCells(r,c,r2,c2,e,v);
    }
    updateCells(r,c,r2,c2,k,v){
        var sr=Math.min(r,r2),
            sc=Math.min(c,c2),
            er=Math.max(r,r2),
            ec=Math.max(c,c2);
        for(r=sr;r<=er;r++){
            for(c=sc;c<=ec;c++){
                this.setCellProp(r,c,k,v);
            }
        }
        this.removeEmptyItem();
    }
    mergeCells(r,c,lr,lc){
        var sel = this.handsontable.getSelected();
        var cell=this.isMergeCell(sel[0],sel[1]);
        // 单个单元格不执行合并操作
        if(r==lr&&c==lc&&cell!=undefined){
            return ;
        }
        // 拆分操作
        if(cell!=undefined) return this.unMergeCells(cell);
        // 合并操作
        // 先合并已经存在的cell
        this.MergeMergeCells(r,c,lr,lc);
        this.sheet.mergecells.push({row: r, col: c, rowspan: lr-r+1, colspan: lc-c+1});
        this.redrawMergeCells();
    }
    unMergeCells(cell){
        this.sheet.mergecells.splice(cell,1);
        this.redrawMergeCells();
    }
    isMergeCell(r,c){
        var i=0,l=this.sheet.mergecells.length,e;
        for(;i<l;i++){
            e=this.sheet.mergecells[i];
            if(e.row<=r&&e.row+e.rowspan-1>=r&&e.col<=c&&e.col+e.colspan-1>=c){
                return i
            }
        }
        return undefined
    }
    MergeMergeCells(r,c,lr,lc){
        // console.log('MergeMergeCells',this.sheet.mergecells);
        var mergeCells=[];
        var i=0,l=this.sheet.mergecells.length,e;
        for(;i<l;i++){
            e=this.sheet.mergecells[i];
            // console.log(e,r<=e.r&&lr>=e.r+e.rowspan-1&&c<=e.c&&lc>=e.c+e.rowspan-1);
            if(r<=e.r&&lr>=e.r+e.rowspan-1&&c<=e.c&&lc>=e.c+e.rowspan-1){
                mergeCells.push(i);
            }
        }
        while(mergeCells.length>0){
            var cell=mergeCells.pop();
            // console.log(cell,this.sheet.mergecells[cell]);
            this.sheet.mergecells.splice(cell,1);
        }
    }
    redrawMergeCells(){
        var mergeCells = new Handsontable.MergeCells(this.sheet.mergecells);
        this.handsontable.mergeCells=mergeCells;
        this.redraw();
    }
 }

export default sheets;